import { spawn, ChildProcess } from 'child_process';
import { EventEmitter } from 'events';
import path from 'path';
import fs from 'fs';
import { WebSocketServer } from 'ws';

export interface ServiceConfig {
  id: string;
  name: string;
  executablePath: string;
  workingDirectory?: string;
  arguments?: string[];
  autoStart?: boolean;
  description?: string;
}

export interface ServiceStatus {
  id: string;
  name: string;
  status: 'running' | 'stopped' | 'error';
  pid?: number;
  startTime?: Date;
  cpu?: number;
  memory?: number;
  description?: string;
}

export class ServiceManager extends EventEmitter {
  private services: Map<string, ServiceConfig> = new Map();
  private processes: Map<string, ChildProcess> = new Map();
  private logs: Map<string, string[]> = new Map();
  private wss: WebSocketServer;
  // 修复 IIS 环境下的路径问题
  // 使用 __dirname 而不是 process.cwd()
  private configFile = path.join(__dirname, '..', '..', 'config', 'services.json');

  constructor(wss: WebSocketServer) {
    super();
    this.wss = wss;
    this.loadConfig();
    this.setupAutoStart();
  }

  // 加载服务配置
  private loadConfig() {
    try {
      console.log(`配置文件路径: ${this.configFile}`);
      
      if (fs.existsSync(this.configFile)) {
        const config = JSON.parse(fs.readFileSync(this.configFile, 'utf8'));
        config.forEach((service: ServiceConfig) => {
          this.services.set(service.id, service);
          this.logs.set(service.id, []);
        });
        console.log(`已加载 ${this.services.size} 个服务配置`);
      } else {
        console.log('配置文件不存在，创建默认配置');
        // 创建默认配置文件
        this.saveConfig();
      }
    } catch (error) {
      console.error('加载服务配置失败:', error);
      console.error('错误详情:', error instanceof Error ? error.stack : error);
    }
  }

  // 保存服务配置
  private saveConfig() {
    try {
      const configDir = path.dirname(this.configFile);
      console.log(`配置目录: ${configDir}`);
      
      if (!fs.existsSync(configDir)) {
        console.log('配置目录不存在，创建目录...');
        fs.mkdirSync(configDir, { recursive: true });
        console.log('目录创建成功');
      }
      
      const config = Array.from(this.services.values());
      fs.writeFileSync(this.configFile, JSON.stringify(config, null, 2));
      console.log(`配置已保存到: ${this.configFile}`);
      console.log(`当前服务数量: ${config.length}`);
    } catch (error) {
      console.error('保存服务配置失败:', error);
      console.error('错误详情:', error instanceof Error ? error.stack : error);
      throw error; // 抛出错误以便上层捕获
    }
  }

  // 自动启动配置的服务
  private setupAutoStart() {
    this.services.forEach((service) => {
      if (service.autoStart) {
        setTimeout(() => {
          this.startService(service.id);
        }, 1000);
      }
    });
  }

  // 启动服务
  async startService(serviceId: string): Promise<boolean> {
    try {
      const service = this.services.get(serviceId);
      if (!service) {
        throw new Error(`服务 ${serviceId} 不存在`);
      }

      if (this.processes.has(serviceId)) {
        throw new Error(`服务 ${service.name} 已在运行中`);
      }

      if (!fs.existsSync(service.executablePath)) {
        throw new Error(`可执行文件不存在: ${service.executablePath}`);
      }

      // 使用spawn启动进程，并隐藏控制台窗口
      const child = spawn(service.executablePath, service.arguments || [], {
        cwd: service.workingDirectory || path.dirname(service.executablePath),
        detached: false,
        stdio: ['ignore', 'pipe', 'pipe'],
        windowsHide: true, // 在Windows上隐藏控制台窗口
      });

      this.processes.set(serviceId, child);
      
      // 记录启动时间
      const startTime = new Date();
      this.addLog(serviceId, `[${startTime.toISOString()}] 服务启动: ${service.name} (PID: ${child.pid})`);

      // 监听标准输出
      child.stdout?.on('data', (data) => {
        const logMessage = data.toString().trim();
        this.addLog(serviceId, `[${new Date().toISOString()}] ${logMessage}`);
        this.broadcastLog(serviceId, logMessage);
      });

      // 监听错误输出
      child.stderr?.on('data', (data) => {
        const errorMessage = data.toString().trim();
        this.addLog(serviceId, `[${new Date().toISOString()}] ERROR: ${errorMessage}`);
        this.broadcastLog(serviceId, errorMessage, 'error');
      });

      // 监听进程退出
      child.on('exit', (code, signal) => {
        this.processes.delete(serviceId);
        const exitMessage = `服务退出: ${service.name} (退出码: ${code}, 信号: ${signal})`;
        this.addLog(serviceId, `[${new Date().toISOString()}] ${exitMessage}`);
        this.broadcastServiceStatus(serviceId);
        console.log(exitMessage);
      });

      child.on('error', (error) => {
        this.processes.delete(serviceId);
        const errorMessage = `服务启动失败: ${service.name} - ${error.message}`;
        this.addLog(serviceId, `[${new Date().toISOString()}] ERROR: ${errorMessage}`);
        this.broadcastServiceStatus(serviceId);
        console.error(errorMessage);
      });

      this.broadcastServiceStatus(serviceId);
      console.log(`服务启动成功: ${service.name} (PID: ${child.pid})`);
      return true;

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '未知错误';
      this.addLog(serviceId, `[${new Date().toISOString()}] ERROR: 启动失败 - ${errorMessage}`);
      console.error(`启动服务失败 ${serviceId}:`, errorMessage);
      return false;
    }
  }

  // 停止服务
  async stopService(serviceId: string): Promise<boolean> {
    try {
      const service = this.services.get(serviceId);
      const process = this.processes.get(serviceId);

      if (!service) {
        throw new Error(`服务 ${serviceId} 不存在`);
      }

      if (!process) {
        throw new Error(`服务 ${service.name} 未在运行`);
      }

      // 尝试优雅关闭
      process.kill('SIGTERM');
      
      // 等待进程关闭
      await new Promise<void>((resolve) => {
        const timeout = setTimeout(() => {
          // 强制关闭
          if (this.processes.has(serviceId)) {
            process.kill('SIGKILL');
          }
          resolve();
        }, 5000);

        process.on('exit', () => {
          clearTimeout(timeout);
          resolve();
        });
      });

      this.addLog(serviceId, `[${new Date().toISOString()}] 服务已停止: ${service.name}`);
      console.log(`服务已停止: ${service.name}`);
      return true;

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '未知错误';
      console.error(`停止服务失败 ${serviceId}:`, errorMessage);
      return false;
    }
  }

  // 重启服务
  async restartService(serviceId: string): Promise<boolean> {
    try {
      await this.stopService(serviceId);
      // 等待一秒后重启
      await new Promise(resolve => setTimeout(resolve, 1000));
      return await this.startService(serviceId);
    } catch (error) {
      console.error(`重启服务失败 ${serviceId}:`, error);
      return false;
    }
  }

  // 获取所有服务状态
  getServicesStatus(): ServiceStatus[] {
    return Array.from(this.services.values()).map(service => {
      const process = this.processes.get(service.id);
      return {
        id: service.id,
        name: service.name,
        status: process ? 'running' : 'stopped',
        pid: process?.pid,
        description: service.description
      };
    });
  }

  // 获取服务日志
  getServiceLogs(serviceId: string, lines: number = 100): string[] {
    const logs = this.logs.get(serviceId) || [];
    return logs.slice(-lines);
  }

  // 添加服务配置
  addService(service: ServiceConfig): boolean {
    try {
      console.log(`正在添加服务: ${service.name} (ID: ${service.id})`);
      console.log(`可执行文件: ${service.executablePath}`);
      
      // 验证服务ID是否已存在
      if (this.services.has(service.id)) {
        console.error(`服务ID ${service.id} 已存在`);
        throw new Error(`服务ID ${service.id} 已存在`);
      }
      
      this.services.set(service.id, service);
      this.logs.set(service.id, []);
      
      console.log('服务添加到内存成功，开始保存配置...');
      this.saveConfig();
      
      console.log(`服务 ${service.name} 添加成功`);
      return true;
    } catch (error) {
      console.error('添加服务失败:', error);
      console.error('错误详情:', error instanceof Error ? error.stack : error);
      // 回滚更改
      this.services.delete(service.id);
      this.logs.delete(service.id);
      return false;
    }
  }

  // 删除服务
  async removeService(serviceId: string): Promise<boolean> {
    try {
      // 先停止服务
      if (this.processes.has(serviceId)) {
        await this.stopService(serviceId);
      }
      
      this.services.delete(serviceId);
      this.logs.delete(serviceId);
      this.saveConfig();
      return true;
    } catch (error) {
      console.error('删除服务失败:', error);
      return false;
    }
  }

  // 添加日志
  private addLog(serviceId: string, message: string) {
    const logs = this.logs.get(serviceId) || [];
    logs.push(message);
    
    // 保持最近1000条日志
    if (logs.length > 1000) {
      logs.splice(0, logs.length - 1000);
    }
    
    this.logs.set(serviceId, logs);
  }

  // 广播日志消息
  private broadcastLog(serviceId: string, message: string, type: string = 'info') {
    const logData = {
      type: 'log',
      serviceId,
      message,
      logType: type,
      timestamp: new Date().toISOString()
    };

    this.wss.clients.forEach((client) => {
      if (client.readyState === 1) { // WebSocket.OPEN
        client.send(JSON.stringify(logData));
      }
    });
  }

  // 广播服务状态
  private broadcastServiceStatus(serviceId: string) {
    const service = this.services.get(serviceId);
    const process = this.processes.get(serviceId);
    
    if (service) {
      const statusData = {
        type: 'status',
        service: {
          id: service.id,
          name: service.name,
          status: process ? 'running' : 'stopped',
          pid: process?.pid,
          description: service.description
        }
      };

      this.wss.clients.forEach((client) => {
        if (client.readyState === 1) {
          client.send(JSON.stringify(statusData));
        }
      });
    }
  }
}